package com.chess.annotation.demo;

import android.graphics.Matrix;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class ZoomViewListener implements OnTouchListener {

	private Matrix matrix = new Matrix();
	private Matrix savedMatrix = new Matrix();

	private State mode = State.NONE;

	private PointF startPoint = new PointF();
	private PointF zoomMidPoint = new PointF();

	private float oldZoomDist = 0;

	private ZoomViewDelegate delegate = null;

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		boolean respondIntercept = false;
		delegate.initZoomViewAction(matrix);

		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			delegate.preZoomViewAction(matrix);
			savedMatrix.set(matrix);
			startPoint.set(event.getX(), event.getY());
			mode = State.DRAG;
			respondIntercept = true;
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			oldZoomDist = MathUtil.getZoomDistance(event);
			if (oldZoomDist > 10f) {
				savedMatrix.set(matrix);
				float[] values = new float[9];
				matrix.getValues(values);
				mode = State.ZOOM;
			}
			respondIntercept = false;
			break;
		case MotionEvent.ACTION_UP:
			delegate.adjustZoomViewPostion(matrix);
			mode = State.NONE;
			respondIntercept = true;
			delegate.postZoomViewAction(matrix);
			break;
		case MotionEvent.ACTION_POINTER_UP:
			delegate.adjustZoomViewScale(matrix, zoomMidPoint.x, zoomMidPoint.y);
			mode = State.NONE;
			respondIntercept = false;
			break;
		case MotionEvent.ACTION_CANCEL:
			delegate.adjustZoomViewScale(matrix, zoomMidPoint.x, zoomMidPoint.y);
			delegate.adjustZoomViewPostion(matrix);
			mode = State.NONE;
			respondIntercept = true;
			break;
		case MotionEvent.ACTION_MOVE:
			if (mode == State.DRAG) {
				if (MathUtil.getDistance(event.getX(), event.getY(), startPoint.x, startPoint.y) > delegate
						.getTouchSlop()) {
					matrix.set(savedMatrix);
					matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
					delegate.adjustZoomViewPostion(matrix);
				}
				respondIntercept = true;
			} else if (mode == State.ZOOM) {
				float newZoomDistance = MathUtil.getZoomDistance(event);

				if (newZoomDistance > delegate.getTouchSlop()) {
					zoomMidPoint = MathUtil.getMidPoint(event);

					matrix.set(savedMatrix);
					float scale = newZoomDistance / oldZoomDist;
					matrix.postScale(scale, scale, zoomMidPoint.x, zoomMidPoint.y);

					delegate.adjustZoomViewScale(matrix, zoomMidPoint.x, zoomMidPoint.y);
					delegate.adjustZoomViewPostion(matrix);

				}
				respondIntercept = false;
			}
			break;
		}
		delegate.doZoomViewAction(matrix);
		return !respondIntercept;

	}

	 

	public void setDelegate(ZoomViewDelegate delegate) {
		this.delegate = delegate;
	}

}
